package com.dog.basics.service.mtkj.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dog.basics.bean.dto.admin.mtkj.LockAddDto;
import com.dog.basics.bean.dto.admin.mtkj.LockEditDto;
import com.dog.basics.bean.dto.admin.mtkj.LockFromDto;
import com.dog.basics.bean.model.common.DogComPositioninfo;
import com.dog.basics.bean.model.mtkj.*;
import com.dog.basics.bean.model.sys.SysUser;
import com.dog.basics.bean.vo.admin.mtkj.LockVo;
import com.dog.basics.bean.vo.api.mtkj.ApiHospitalCostVo;
import com.dog.basics.bean.vo.api.mtkj.ApiLockVo;
import com.dog.basics.common.util.PageParam;
import com.dog.basics.dao.common.DogComPositioninfoMapper;
import com.dog.basics.dao.mtkj.*;
import com.dog.basics.dao.sys.SysUserMapper;
import com.dog.basics.security.util.SecurityUtils;
import com.dog.basics.service.mtkj.IMtDeviceLockService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 设备锁 服务实现类
 * </p>
 *
 * @author wph
 * @since 2020-09-29
 */
@Service
@AllArgsConstructor
public class MtDeviceLockServiceImpl extends ServiceImpl<MtDeviceLockMapper, MtDeviceLock> implements IMtDeviceLockService {
    private final DogComPositioninfoMapper dogComPositioninfoMapper;
    private final SysUserMapper sysUserMapper;
    private final MtDeviceHospitalMapper mtDeviceHospitalMapper;
    private final MtDeviceDepositMapper mtDeviceDepositMapper;
    private final MtDeviceHospitalCostMapper mtDeviceHospitalCostMapper;
    private final MtDeviceLockPassMapper mtDeviceLockPassMapper;


    /**
     * 分页的条件公用类
     *
     * @param name,mobile
     * @param userIds
     */
    public List<Long> getuserIdsWhere(String name, String mobile, List<Long> userIds) {
        List<Long> collect = sysUserMapper.selectList(Wrappers.<SysUser>lambdaQuery().like(StrUtil.isNotBlank(mobile), SysUser::getMobile, mobile).like(StrUtil.isNotBlank(name), SysUser::getUsername, name)).stream().map(e -> e.getUserId()).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(collect)) {
            userIds = collect;
        } else {
            userIds.add(-2L);
        }
        return userIds;
    }

    /**
     * 分页的条件公用类
     *
     * @param name,mobile
     * @param hospitalIds
     */
    public List<Long> getHospitalIdsWhere(String name, List<Long> hospitalIds) {
        List<Long> collect = mtDeviceHospitalMapper.selectList(Wrappers.<MtDeviceHospital>lambdaQuery().like(StrUtil.isNotBlank(name), MtDeviceHospital::getHospitalName, name)).stream().map(e -> e.getId()).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(collect)) {
            hospitalIds = collect;
        } else {
            hospitalIds.add(-2L);
        }
        return hospitalIds;
    }

    /**
     * @Description: 分页设备锁
     * @Param: status
     * @return: IPage<LockVo>
     * @Author: wph
     * @Date:
     */
    @Override
    public IPage<LockVo> getPageList(PageParam page, LockFromDto obj) {
        Long userId = null;
        //权限判断
        if (SecurityUtils.getSysUser().getAccountType() == 2) {
            userId = SecurityUtils.getSysUser().getUserId();

        }
        // 判断所属用户ID
        List<Long> userIds = CollUtil.newArrayList();
        if (StrUtil.isNotBlank(obj.getUserName()) || StrUtil.isNotBlank(obj.getUserMobile())) {
            userIds = getuserIdsWhere(obj.getUserName(), obj.getUserMobile(), userIds);
        }
        // 判断所属医院ID
        List<Long> hospitalIds = CollUtil.newArrayList();
        if (StrUtil.isNotBlank(obj.getHospitalName())) {
            hospitalIds = getHospitalIdsWhere(obj.getHospitalName(), hospitalIds);
        }
        IPage iPage = this.page(page, new LambdaQueryWrapper<MtDeviceLock>()
                .eq(ObjectUtil.isNotNull(userId), MtDeviceLock::getDevAgentUserId, userId)
                .in(CollUtil.isNotEmpty(hospitalIds), MtDeviceLock::getHospitalId, hospitalIds)
                .in(CollUtil.isNotEmpty(userIds), MtDeviceLock::getDevAgentUserId, userIds)
                .like(StrUtil.isNotBlank(obj.getDevCode()), MtDeviceLock::getDevCode, obj.getDevCode())
                .like(StrUtil.isNotBlank(obj.getDevName()), MtDeviceLock::getDevName, obj.getDevName())
                .like(StrUtil.isNotBlank(obj.getDevBluetoothName()), MtDeviceLock::getDevBluetoothName, obj.getDevBluetoothName())
                .like(StrUtil.isNotBlank(obj.getDetailedAddress()), MtDeviceLock::getDetailedAddress, obj.getDetailedAddress())
                .eq(ObjectUtil.isNotNull(obj.getDevType()), MtDeviceLock::getDevType, obj.getDevType())
                .eq(ObjectUtil.isNotNull(obj.getDevOnlineState()), MtDeviceLock::getDevOnlineState, obj.getDevOnlineState())
                .eq(ObjectUtil.isNotNull(obj.getDevStatus()), MtDeviceLock::getDevStatus, obj.getDevStatus())
                .eq(ObjectUtil.isNotNull(obj.getDevInitializeState()), MtDeviceLock::getDevInitializeState, obj.getDevInitializeState())
                .eq(ObjectUtil.isNotNull(obj.getProvinceId()), MtDeviceLock::getProvinceId, obj.getProvinceId())
                .eq(ObjectUtil.isNotNull(obj.getCityId()), MtDeviceLock::getCityId, obj.getCityId())
                .eq(ObjectUtil.isNotNull(obj.getAreaId()), MtDeviceLock::getAreaId, obj.getAreaId())
                .orderBy(Boolean.TRUE, obj.getIsOrderByAvg(), MtDeviceLock::getCreateTime));
        List<MtDeviceLock> records = iPage.getRecords();
        iPage.setRecords(records.stream().map(e -> {
            LockVo newsVo = BeanUtil.toBean(e, LockVo.class);
            //查询
            SysUser sysUser = sysUserMapper.selectById(e.getDevAgentUserId());
            DogComPositioninfo province = dogComPositioninfoMapper.selectById(e.getProvinceId());
            DogComPositioninfo city = dogComPositioninfoMapper.selectById(e.getCityId());
            DogComPositioninfo area = dogComPositioninfoMapper.selectById(e.getAreaId());
            MtDeviceHospital mtDeviceHospital = mtDeviceHospitalMapper.selectById(e.getHospitalId());
            newsVo.setUserName(ObjectUtil.isNotNull(sysUser) ? sysUser.getUsername() : "");
            newsVo.setUserMobile(ObjectUtil.isNotNull(sysUser) ? sysUser.getMobile() : "");
            newsVo.setProvinceName(ObjectUtil.isNotNull(province) ? province.getAreaName() : "");
            newsVo.setCityName(ObjectUtil.isNotNull(city) ? city.getAreaName() : "");
            newsVo.setAreaName(ObjectUtil.isNotNull(area) ? area.getAreaName() : "");
            newsVo.setHospitalName(ObjectUtil.isNotNull(mtDeviceHospital) ? mtDeviceHospital.getHospitalName() : "");
            return newsVo;
        }).collect(Collectors.toList()));
        return iPage;
    }

    /**
     * @Description: 设备锁详情
     * @Param: id
     * @return: ApiLockVo
     * @Author: wph
     * @Date:
     */
    @Override
    public ApiLockVo getApiObjXq(Long id) {
        MtDeviceLock dogNews = this.getById(id);
        Validator.validateNotNull(dogNews, "无此数据!");
        //判断是否绑定
        Validator.validateFalse(Validator.equal(dogNews.getDevAgentUserId(), 1L), "该设备锁还未绑定");
        Validator.validateFalse(Validator.equal(dogNews.getHospitalId(), 1L), "该设备锁还未绑定");
        Validator.validateEqual(dogNews.getDevOnlineState(), 1, "该设备处于离线");
        Validator.validateEqual(dogNews.getDevInitializeState(), 1, "该设备还未初始化");
        Validator.validateFalse(Validator.equal(dogNews.getDevStatus(), 2), "该设备锁已经故障");
        ApiLockVo apiLockVo = new ApiLockVo();
        BeanUtil.copyProperties(dogNews, apiLockVo);
        //判断是否缴纳押金
        List<MtDeviceDeposit> list = mtDeviceDepositMapper.selectList(Wrappers.<MtDeviceDeposit>lambdaQuery().eq(MtDeviceDeposit::getDepositState, 1).eq(MtDeviceDeposit::getDepositUserId, SecurityUtils.getUser().getUserId()));
        if (CollUtil.isNotEmpty(list)) {
            apiLockVo.setSfDeposit(1);
        } else {
            apiLockVo.setSfDeposit(0);
        }
        MtDeviceHospital mtDeviceHospital = mtDeviceHospitalMapper.selectById(dogNews.getHospitalId());
        Validator.validateNotNull(mtDeviceHospital, "医院不存在!");
        List<MtDeviceHospitalCost> mtDeviceHospitalCostList = mtDeviceHospitalCostMapper.selectList(Wrappers.<MtDeviceHospitalCost>lambdaQuery().eq(MtDeviceHospitalCost::getDeviceHospitalId, dogNews.getHospitalId()).orderByDesc(MtDeviceHospitalCost::getCreateTime));
        if (CollUtil.isNotEmpty(mtDeviceHospitalCostList)) {
            ApiHospitalCostVo apiHospitalCostVo = new ApiHospitalCostVo();
            BeanUtil.copyProperties(mtDeviceHospitalCostList.get(0), apiHospitalCostVo);
            apiLockVo.setApiHospitalCostVo(apiHospitalCostVo);
        }
        return apiLockVo;
    }

    /**
     * @Description: 增加设备锁
     * @Param: obj
     * @return: Boolean
     * @Author: wph
     * @Date: 2020/05/19  0027
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveObj(LockAddDto obj) {
/*        DogComPositioninfo province = dogComPositioninfoMapper.selectById(obj.getProvinceId());
        Validator.validateNotNull(province, "省不存在!");
        DogComPositioninfo city = dogComPositioninfoMapper.selectById(obj.getCityId());
        Validator.validateNotNull(city, "市不存在!");
        DogComPositioninfo area = dogComPositioninfoMapper.selectById(obj.getAreaId());
        Validator.validateNotNull(area, "区不存在!");*/
        MtDeviceLock dogNews = new MtDeviceLock();
        BeanUtil.copyProperties(obj, dogNews);
        if (ObjectUtil.isNotNull(obj.getDevAgentUserId()) && obj.getDevAgentUserId() != -1L) {
            SysUser sysUser = sysUserMapper.selectById(obj.getDevAgentUserId());
            Validator.validateNotNull(sysUser, "代理商不存在!");
            MtDeviceHospital mtDeviceHospital = mtDeviceHospitalMapper.selectById(obj.getHospitalId());
            Validator.validateNotNull(mtDeviceHospital, "医院不存在!");
            Validator.validateEqual(mtDeviceHospital.getHospitalAgentUserId(), obj.getDevAgentUserId(), "所选医院和代理商不匹配!");
            dogNews.setProvinceId(mtDeviceHospital.getProvinceId());
            dogNews.setCityId(mtDeviceHospital.getCityId());
            dogNews.setAreaId(mtDeviceHospital.getAreaId());
        } else {
            dogNews.setHospitalId(-1L);
            dogNews.setDevAgentUserId(-1L);
        }
        //判断编号是否存在
        List<MtDeviceLock> list = this.list(Wrappers.<MtDeviceLock>lambdaQuery().eq(MtDeviceLock::getDevCode, obj.getDevCode()));
        Validator.validateFalse(CollUtil.isNotEmpty(list), "设备已经存在!");


        dogNews.setCreateTime(DateUtil.currentSeconds());
        dogNews.setCreateBy(SecurityUtils.getSysUser().getUserId());
        Validator.validateTrue(this.save(dogNews), "数据保存失败!");
        //生成锁通道
        for (int i = 1; i < 7; i++) {
            MtDeviceLockPass mtDeviceLockPass = new MtDeviceLockPass();
            mtDeviceLockPass.setPassNum(i + "");
            mtDeviceLockPass.setLockId(dogNews.getId());
            mtDeviceLockPass.setCreateTime(DateUtil.currentSeconds());
            mtDeviceLockPass.setCreateBy(SecurityUtils.getSysUser().getUserId());
            Validator.validateTrue(retBool(mtDeviceLockPassMapper.insert(mtDeviceLockPass)), "数据保存失败!");
        }
        return Boolean.TRUE;
    }

    /**
     * @Description: 修改设备锁
     * @Param: obj
     * @return: Boolean
     * @Author: wph
     * @Date: 2020/05/19  0027
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean editObj(LockEditDto obj) {
        MtDeviceLock dogNews = this.getById(obj.getId());
        BeanUtil.copyProperties(obj, dogNews);
        Validator.validateNotNull(dogNews, "无此数据!");
/*        DogComPositioninfo province = dogComPositioninfoMapper.selectById(obj.getProvinceId());
        Validator.validateNotNull(province, "省不存在!");
        DogComPositioninfo city = dogComPositioninfoMapper.selectById(obj.getCityId());
        Validator.validateNotNull(city, "市不存在!");
        DogComPositioninfo area = dogComPositioninfoMapper.selectById(obj.getAreaId());
        Validator.validateNotNull(area, "区不存在!");*/
        if (ObjectUtil.isNotNull(obj.getDevAgentUserId()) && obj.getDevAgentUserId() != -1L) {
            SysUser sysUser = sysUserMapper.selectById(obj.getDevAgentUserId());
            Validator.validateNotNull(sysUser, "代理商不存在!");
            //List<MtDeviceHospital> list = mtDeviceHospitalMapper.selectList(Wrappers.<MtDeviceHospital>lambdaQuery().eq(MtDeviceHospital::getId, obj.getHospitalId()).eq(MtDeviceHospital::getHospitalAgentUserId, obj.getDevAgentUserId()));
            //Validator.validateTrue(CollUtil.isNotEmpty(list), "所选医院和代理商不匹配!");
            MtDeviceHospital mtDeviceHospital = mtDeviceHospitalMapper.selectById(obj.getHospitalId());
            Validator.validateNotNull(mtDeviceHospital, "医院不存在!");
            Validator.validateEqual(mtDeviceHospital.getHospitalAgentUserId(), obj.getDevAgentUserId(), "所选医院和代理商不匹配!");
            dogNews.setProvinceId(mtDeviceHospital.getProvinceId());
            dogNews.setCityId(mtDeviceHospital.getCityId());
            dogNews.setAreaId(mtDeviceHospital.getAreaId());
        } else {
            dogNews.setHospitalId(-1L);
            dogNews.setDevAgentUserId(-1L);
        }
        //判断编号是否存在
        List<MtDeviceLock> list = this.list(Wrappers.<MtDeviceLock>lambdaQuery().ne(MtDeviceLock::getId, obj.getId()).eq(MtDeviceLock::getDevCode, obj.getDevCode()));
        Validator.validateFalse(CollUtil.isNotEmpty(list), "设备已经存在!");
        dogNews.setUpdateTime(DateUtil.currentSeconds());
        dogNews.setUpdateBy(SecurityUtils.getSysUser().getUserId());
        Validator.validateTrue(this.updateById(dogNews), "修改数据失败!");
        return Boolean.TRUE;
    }

    /**
     * @Description: 删除设备锁
     * @Param: ids
     * @return: Boolean
     * @Author: wph
     * @Date: 2020/05/19  0027
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteObj(Long id) {
        MtDeviceLock dogNews = this.getById(id);
        Validator.validateNotNull(dogNews, "无此数据!");
        Validator.validateTrue(this.removeById(id), "数据删除失败!");
        List<MtDeviceLockPass> list = mtDeviceLockPassMapper.selectList(Wrappers.<MtDeviceLockPass>lambdaQuery().eq(MtDeviceLockPass::getLockId, id));
        Validator.validateFalse(CollUtil.isNotEmpty(list), "请先删除锁通道");
        return Boolean.TRUE;
    }

    /**
     * @Description: 设备锁在线离线
     * @Param: LockEditDto
     * @return: Boolean
     * @Author: wph
     * @Date: 2020/05/19  0027
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean editOnline(Long id) {
        MtDeviceLock dogNews = this.getById(id);
        Validator.validateNotNull(dogNews, "无此数据!");
        dogNews.setDevOnlineState(dogNews.getDevOnlineState() == 0 ? 1 : 0);
        Validator.validateTrue(this.updateById(dogNews), "修改数据失败!");
        return Boolean.TRUE;
    }

    /**
     * @功能描述: 锁-异常上报 (以供使用)
     * @author He
     * @date 2020/10/13
     */
    @Override
    public Boolean editAbnormalReport(Long id, Integer lckport, String exCode) {
        // 根据标识查询锁信息
        MtDeviceLock deviceLock = this.getById(id);
        // 判断锁是否不存在
        if (ObjectUtil.isNull(deviceLock)) {
            return Boolean.FALSE;
        }
        // 修改锁为故障状态并且添加故障类型
        String lckportStr = StrUtil.toString(lckport);
        List<MtDeviceLockPass> mtDeviceLockPasses = mtDeviceLockPassMapper.selectList(Wrappers.<MtDeviceLockPass>lambdaQuery().eq(MtDeviceLockPass::getLockId, id).eq(MtDeviceLockPass::getPassNum, lckportStr));
        if (CollUtil.isEmpty(mtDeviceLockPasses)) {
            return Boolean.FALSE;
        }
        MtDeviceLockPass deviceLockPass = new MtDeviceLockPass();
        deviceLockPass.setId(mtDeviceLockPasses.get(0).getId());
        deviceLockPass.setRemarksOne(Validator.equal(lckportStr, "0") ? "0" : "1");
        deviceLockPass.setRemarksTow(exCode);
        deviceLockPass.setUpdateTime(DateUtil.currentSeconds());
        return retBool(this.mtDeviceLockPassMapper.updateById(deviceLockPass));
    }
}
